/*
 * Can.h
 *
 *  Created on: 5 nov. 2010
 *      Author: eric
 */

#ifndef CAN1_H_
#define CAN1_H_

#include "Arduino.h"         // include types & constants of Wiring core API

#include "CanDef.h"
#include "Spi.h"
#include <inttypes.h>

const byte mntCNF1[4] = { b500k, b250k, b125k, b50k };
const byte mntCNF2 = (0x80 + ((tps1) << 3) + (tprop));
const byte mntCNF3 = tps2;

#define CAN_INT	9 // pin 9 arduino nano

class Can {
public:
	typedef struct {
		byte byteHi;
		byte byteLo;
	} byte2;

	union uint32_b4 {
		uint32_t uID;
		byte bID[4];
	};

	typedef struct {
		uint16_t i16Hi;
		uint16_t i16Lo;
	} uint16_2;

	typedef struct {
		byte2 i16Hi;
		byte2 i16Lo;
	} byte4;

	typedef struct {
		uint32_t ID;
		byte nbytes;
		boolean rtr;
		byte data[8];
	} CAN_MSG;

	enum {
		_OPERATION_, _SLEEP_, _LOOPBACK_, _LISTENONLY_, _CONFIGURATION_
	};

	enum {
		B500K, B250K, B125K, B50K
	};

	/**************************************************************************
	 This function returns the global status variable.
	 The status can be changed anytime by this module,
	 for example from within an interrupt service routine or by any of the other
	 functions in this module.
	 Returns
	 BITS:
	 0: INIT - set to 1 after a completed initialization left 0 if not yet inited or init failed
	 1: CERR - set to 1 if a CAN bit or frame error occured *
	 2: ERPA - set to 1 if a CAN "error passive" occured
	 3: RXOR - set to 1 if a receive queue overrun occured
	 4: TXOR - set to 1 if a transmit queue overrun occured *
	 5: Reserved
	 6: Reserved
	 7: BOFF - set to 1 if a CAN "bus off" error occured
	 **************************************************************************/
	byte getStatus(void);
	/**************************************************************************
	 This function implements the initialization of the CAN interface.
	 Returns:
	 1 if init is completed
	 0 if init failed, bit INIT of GetStatus stays 0
	 **************************************************************************/
	byte init();
	/**************************************************************************
	 This function implements a CAN send message
	 Return:
	 true Message disponible
	 false No message
	 **************************************************************************/
	boolean checkMessage(void);
	/**************************************************************************
	 This function implements a CAN send message
	 Return:
	 true Message was sent
	 false Message not send
	 **************************************************************************/
	boolean sendMessage(CAN_MSG *pTransmitBuf);
	/**************************************************************************
	 This function implements a CAN receive queue. With each
	 function call a message is pulled from the queue.
	 Return:
	 true Message was read
	 false Message not read
	 **************************************************************************/
	boolean readMessage(CAN_MSG *pTransmitBuf);
	/**************************************************************************
	 This function implements a change to operation mode
	 Returns:
	 true = correctly changed
	 false = bad mode requested
	 AVAILABLE OPTIONS:
	 0	_OPERATION_
	 1	_SLEEP_
	 2 	_LOOPBACK_
	 3 	_LISTENONLY_
	 4	_CONFIGURATION_
	 **************************************************************************/
	boolean setMode(byte _mode);
private:
	boolean init_done;
	boolean tx_nospace;
	/**************************************************************************
	 This function implements a soft reset to Can core
	 **************************************************************************/
	void reset(void);
	/**************************************************************************
	 This function implements a write access to Can internal registers
	 The contents for register RegAdd is updated to RegValue
	 **************************************************************************/
	void writeRegister(byte RegAdd, byte RegValue);
	/**************************************************************************
	 This function implements a read access to Can internal registers
	 Returns:
	 The register contents at RegAdd
	 **************************************************************************/
	byte readRegister(byte RegAdd);
	byte readStatus();
	byte readRxStatus();
	/**************************************************************************
	 This function implements a bit change
	 Only masked bits at RegAdd
	 **************************************************************************/
	void bitMod(byte RegAdd, byte RegMask, byte RegValue);
	byte4 setSID(uint32_t ID);
	uint32_t getSID(byte4 DoubleInt16);
	byte2 move16to8(uint16_t Value);
	uint16_2 move32to16(uint32_t Value);
	uint16_t move8to16(byte2 DoubleByte);
};

#endif /* CAN1_H_ */
